package com.example.naodian.service.impl;

import com.example.naodian.domain.dto.PageDto;
import com.example.naodian.domain.po.Warning;
import com.example.naodian.domain.vo.EegDataBlockVO;
import com.example.naodian.service.IEegDataBlockService;
import com.example.naodian.service.IScheduledTasksService;
import com.example.naodian.service.IUserService;
import com.example.naodian.websocket.WebSocketServer;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.ScheduledFuture;

/**
 * 定时任务服务实现类
 * 该类负责管理定时任务的启动、停止和重置。
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ScheduledTasksServiceImpl implements IScheduledTasksService {
    // WebSocket服务器，用于广播消息
    private final WebSocketServer webSocketServer;
    // 任务调度器，用于调度定时任务
    private final TaskScheduler taskScheduler;
    // 预警服务，用于处理预警信息
    private final WarningServiceImpl warningService;
    // 用户服务，用于获取用户信息
    private final IUserService userService;
    // EEG数据块服务，用于查询EEG数据
    private final IEegDataBlockService eegDataBlockService;
    // 存储定时任务的Future对象
    private ScheduledFuture<?> scheduledFuture;

    // 用于存储当前页码
    private int page = 1;
    // 用于存储PageDto参数
    private PageDto pageDto;

    /**
     * 初始化方法，在Bean初始化后调用
     * 初始化时不启动定时任务
     */
    @PostConstruct
    public void init() {
        // 初始化时不启动定时任务
    }

    /**
     * 开启定时查询预警信息
     * @param interval 间隔时间（毫秒）
     */
    public void startWarningTask(long interval) {
        // 检查当前是否有未取消的定时任务
        if (scheduledFuture == null || scheduledFuture.isCancelled()) {
            // 调度定时任务，每隔interval毫秒执行一次scheduledWarningTask方法
            scheduledFuture = taskScheduler.scheduleAtFixedRate(this::scheduledWarningTask, interval);
        }
    }

    /**
     * 开始定时查询数据信息
     * @param interval 间隔时间（毫秒）
     * @param pageDto 分页参数
     */
    @Override
    public void startEegList(long interval, PageDto pageDto) {
        // 存储传入的PageDto参数
        this.pageDto = pageDto;
        // 检查当前是否有未取消的定时任务
        if (scheduledFuture == null || scheduledFuture.isCancelled()) {
            // 调度定时任务，每隔interval毫秒执行一次scheduledEegTask方法
            scheduledFuture = taskScheduler.scheduleAtFixedRate(this::scheduledEegTask, interval);
            log.info("定时任务已开启.");
        }
    }

    /**
     * 停止定时任务
     */
    public void stopTask() {
        // 检查当前是否有未取消的定时任务
        if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
            // 取消定时任务，并尝试中断正在执行的任务线程
            scheduledFuture.cancel(true);
            log.info("定时任务已停止.");
        }
        // 清理scheduledFuture，确保资源得到释放
        scheduledFuture = null;
    }

    /**
     * 重置定时任务
     */
    @Override
    public void resetTask() {
        // 检查当前是否有未取消的定时任务
        if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
            // 取消定时任务，并尝试中断正在执行的任务线程
            scheduledFuture.cancel(true);
            log.info("定时任务已重置.");
        }
        // 清理scheduledFuture，确保资源得到释放
        scheduledFuture = null;
        // 重置页码
        page = 1;
        // 清理pageDto，确保下次启动定时任务时需要重新设置PageDto参数
        pageDto = null;
        log.info("定时任务已重置.");
    }

    /**
     * 执行定时查询预警代码
     */
    public void scheduledWarningTask() {
        // 查询用户预警值
        // 注释掉的代码是根据当前登录用户ID查询预警值
        // Double value = userService.getWarningValueByUserId(BaseContext.getCurrentId());
        Double value = userService.getWarningValueByUserId(1L); // 使用固定用户ID 1L 进行模拟

        // 1. 判断预警值是否为空
        if (value == null) {
            // 设置默认值
            value = 50.00;
        }

        // 2. 判断预警值是否低于40，触发疲劳预警
        if (value < 40) {
            Warning warning = new Warning();
            // 设置预警的用户ID
            // warning.setUserId(BaseContext.getCurrentId()); // 当前登录用户ID
            warning.setUserId(1L); // 使用固定用户ID 1L 进行模拟
            warning.setType(1); // 预警类型1
            warning.setDes("疲劳预警"); // 预警描述
            warning.setEegRecordingId(1L); // EEG记录ID
            warningService.insert(warning); // 插入预警信息到数据库
            webSocketServer.broadcast(warning.getDes()); // 广播预警信息
        }

        // 3. 判断预警值是否在60到70之间，触发分心预警
        if (value > 60 && value < 70) {
            Warning warning = new Warning();
            // 设置预警的用户ID
            // warning.setUserId(BaseContext.getCurrentId()); // 当前登录用户ID
            warning.setUserId(1L); // 使用固定用户ID 1L 进行模拟
            warning.setType(2); // 预警类型2
            warning.setDes("分心预警"); // 预警描述
            warning.setEegRecordingId(1L); // EEG记录ID
            warningService.insert(warning); // 插入预警信息到数据库
            webSocketServer.broadcast(warning.getDes()); // 广播预警信息
        }
    }

    /**
     * 执行定时查询eeg数据代码
     */
    private void scheduledEegTask() {
        // 检查PageDto是否为空
        if (pageDto != null) {
            // 设置当前页码
            pageDto.setPage((page - 1) * pageDto.getPageSize());
            // 设置每页大小
            pageDto.setPageSize(30);
            log.info("现在是第几页: {}", page);
            // 查询EEG数据块列表
            List<EegDataBlockVO> eegDataBlockVOList = eegDataBlockService.pageQuery(pageDto);
            // 广播查询结果
            webSocketServer.broadcast(eegDataBlockVOList.toString());

            // 更新当前页码
            page++;
        } else {
            // 如果PageDto未初始化，记录错误日志
            log.error("PageDto 未初始化.");
        }
    }
}
